<?php

namespace services\statistics;

use Yii;
use services\common\CommonService;
use common\models\clinic\Doctor;
use common\models\clinic\Project;
use common\models\clinic\UserTreatment;
use common\models\marketing\OutpatientType;
use common\models\patient\Consumption;
use common\models\statistics\ProjectReport;
use yii\web\HttpException;
use common\components\Service;
use common\models\base\PatientDiseases;
use common\models\patient\User;

/**
 * Class ProjectReportService
 * @package services\statistics
 */
class ProjectReportService extends Service
{
    /**
     * 统计报表列表
     *
     * @param array $params
     * @return array
     */
    public function getList(array $params = [])
    {
        $startTime = strtotime(date($params['start_time']));
        $endTime = strtotime(date($params['end_time'])) + 86399;
        $where = [];
        if (isset($params['patient_diseases_id'])) {
            if (is_numeric($params['patient_diseases_id'])) {// 数字包括0
                $where['b.patient_diseases_id'] = $params['patient_diseases_id'];
            } elseif ($params['patient_diseases_id']) { //字符串1,2
                $diseasesIds = explode(',', $params['patient_diseases_id']);
                if ($diseasesIds) {
                    $where['b.patient_diseases_id'] = $diseasesIds;
                }
            } else {
                $diseasesList = PatientDiseases::find()
                    ->select('id')
                    ->where(['status' => PatientDiseases::STATUS_ENABLE, 'pid' => 0])
                    ->column();
                array_push($diseasesList, 0);
                $where['b.patient_diseases_id'] = $diseasesList;
            }
        }
        $list1 = [];
        $list2 = [];
        $list3 = [];
        if (in_array($params['check_type'], [1,2,4,6,7])) { // 消费列表
            $list1 = Consumption::find()
                ->select([
                    'a.project_id', 'a.patient_card_id', 'a.clinic_time',
                    'a.reality_money', 'b.patient_diseases_id', 'b.outpatient_type_id'
                ])
                ->alias('a')
                ->innerJoin(User::tableName() . ' b', 'a.patient_card_id = b.patient_card_id and a.project_id = b.project_id')
                ->where([
                    'and',
                    ['between', 'a.clinic_time', $startTime, $endTime],
                    ['b.status' => User::STATUS_ENABLE],
                ])
                ->andWhere($where)
                ->asArray()
                ->all();
        }
        if (in_array($params['check_type'], [8,9])) { // 308人均使用、308人均购买
            $list2 = UserTreatment::find()
                ->select([
                    'a.project_id', 'a.patient_card_id', 'a.recently_clinic_time', 'a.type',
                    'a.recently_clinic_num', 'a.recently_surplus_num', 'b.patient_diseases_id', 'b.outpatient_type_id',
                ])
                ->alias('a')
                ->innerJoin(User::tableName() . ' b', 'a.patient_card_id = b. patient_card_id and a.project_id = b.project_id')
                ->leftJoin(Project::tableName() . ' c', ' a.clinic_project_id = c.id and a.project_id = c.project_id')
                ->where([
                    'and',
                    [
                        'c.template' => Project::TEMPLATE_308,
                        'b.status' => User::STATUS_ENABLE
                    ],
                    ['>=', 'a.recently_clinic_time', $startTime],
                    ['<=', 'a.recently_clinic_time', $endTime]
                ])
                ->andWhere($where)
                ->asArray()
                ->all();
        }
        if (in_array($params['check_type'], [2,3,4,5,6,7])) { // 人数
            if (in_array($params['check_type'], [3,4,5,6,7])) {
                $timeIs = 'b.last_revisiting_time';
            } else {
                $timeIs = 'b.reg_time';
            }
            $list3 = User::find()
                ->alias('b')
                ->select(['b.patient_diseases_id', 'b.outpatient_type_id', 'b.project_id', 'b.patient_card_id'])
                ->where([
                    'and',
                    ['b.status' => User::STATUS_ENABLE],
                    ['>=', $timeIs, $startTime],
                    ['<=', $timeIs, $endTime]
                ])
                ->andWhere($where)
                ->asArray()
                ->all();
        }
        // 列表返回
        $arr = $this->getListPageFormat($list1, $list2, $list3, $params, 'project_id');
        // return $arr;
        $finalArr = [];

        // 绑定项目列表
        $projectList = CommonService::getBindProjectList();
        if ($arr) {
            foreach ($arr as $key => $val) {
                $projectIs = \common\models\base\Project::findOne($key);
                $projectName = $projectIs ? $projectIs->name : '';
                $status = 0;// 能否点详细
                if (in_array($key, array_column($projectList, 'id'))) {
                    $status = 1;
                }
                $finalArr[] = [
                    'data' => round($val['data'], 2),
                    'project_id' => $key,
                    'name' => $projectName,
                    'rank' => '-',
                    'status' => $status,
                ];
            }
            array_multisort($finalArr, SORT_DESC);
        }
        return $this->compareLastMonth($params, $finalArr);
    }

    /**
     * 格式化列表
     *
     * @param array $list1
     * @param array $list2
     * @param array $list3
     * @param array $params
     * @return array
     */
    public function getListPageFormat(array $list1 = [], array $list2 = [], array $list3 = [], array $params = [], $paramsId)
    {
        $arr = [];
        if ($params['check_type'] == 1) { //总业绩
            foreach ($list1 as $val) {
                // 总消费
                if (isset($arr[$val[$paramsId]]['data'])) {
                    $arr[$val[$paramsId]]['data'] += $val['reality_money'];
                } else {
                    $arr[$val[$paramsId]]['data'] = $val['reality_money'];
                }
            }
        } elseif ($params['check_type'] == 2) { //挂号人均
            // 挂号患者诊疗号数组
            $patientCardArr = [];
            foreach ($list3 as $val) {
                // 挂号人数
                if (isset($arr[$val[$paramsId]]['register_num'])) {
                    $arr[$val[$paramsId]]['register_num'] += 1;
                } else {
                    $arr[$val[$paramsId]]['register_num'] = 1;
                }
                // 挂号患者诊疗号数组
                $patientCardArr[$val[$paramsId]]['patient_card_id'][] = $val['patient_card_id'];
            }
            foreach ($list1 as $key => $val) {
                if (
                    isset($patientCardArr[$val[$paramsId]]['patient_card_id']) &&
                    in_array($val['patient_card_id'], $patientCardArr[$val[$paramsId]]['patient_card_id'])
                ) {
                    // 挂号患者总消费
                    if (isset($arr[$val[$paramsId]]['register_consumption'])) {
                        $arr[$val[$paramsId]]['register_consumption'] += $val['reality_money'];
                    } else {
                        $arr[$val[$paramsId]]['register_consumption'] = $val['reality_money'];
                    }
                }
            }
            // 计算挂号人均
            foreach ($arr as $key => $val) {
                $arr[$key]['data'] = 0;
                if (isset($val['register_num']) && $val['register_num']) {
                    $arr[$key]['data'] = (isset($val['register_consumption']) ? $val['register_consumption'] : 0) / $val['register_num'];
                }
            }
        } elseif ($params['check_type'] == 3) { //初诊人数
            foreach ($list3 as $val) {
                // 患者就诊类型为初诊
                if ($val['outpatient_type_id'] == OutpatientType::ID_FIRST_VISIT) {
                    // 初诊人数（状态为初诊的患者数）
                    if (isset($arr[$val[$paramsId]]['data'])) {
                        $arr[$val[$paramsId]]['data'] += 1;
                    } else {
                        $arr[$val[$paramsId]]['data'] = 1;
                    }
                }
            }
        } elseif ($params['check_type'] == 4) { //初诊人均
            foreach ($list1 as $val) {
                // 患者就诊类型为初诊
                if ($val['outpatient_type_id'] == OutpatientType::ID_FIRST_VISIT) {
                    // 初诊总消费
                    if (isset($arr[$val[$paramsId]]['first_visit_consumption'])) {
                        $arr[$val[$paramsId]]['first_visit_consumption'] += $val['reality_money'];
                    } else {
                        $arr[$val[$paramsId]]['first_visit_consumption'] = $val['reality_money'];
                    }
                }
            }
            foreach ($list3 as $val) {
                // 患者就诊类型为初诊
                if ($val['outpatient_type_id'] == OutpatientType::ID_FIRST_VISIT) {
                    // 初诊人数（状态为初诊的患者数）
                    if (isset($arr[$val[$paramsId]]['first_visit_num'])) {
                        $arr[$val[$paramsId]]['first_visit_num'] += 1;
                    } else {
                        $arr[$val[$paramsId]]['first_visit_num'] = 1;
                    }
                }
            }
            // 初诊人均
            foreach ($arr as $key => $val) {
                $arr[$key]['data'] = 0;
                if (isset($val['first_visit_num']) && $val['first_visit_num']) {
                    $arr[$key]['data'] = (isset($val['first_visit_consumption']) ? $val['first_visit_consumption'] : 0) / $val['first_visit_num'];
                }
            }
        } elseif ($params['check_type'] == 5) { //复诊人数
            foreach ($list3 as $val) {
                // 患者就诊类型为复诊
                if ($val['outpatient_type_id'] == OutpatientType::ID_CONTINUE_VISIT) {
                    // 复诊人数（状态为复诊的患者数）
                    if (isset($arr[$val[$paramsId]]['data'])) {
                        $arr[$val[$paramsId]]['data'] += 1;
                    } else {
                        $arr[$val[$paramsId]]['data'] = 1;
                    }
                }
            }
        } elseif ($params['check_type'] == 6) { //复诊人均
            foreach ($list1 as $val) {
                // 患者就诊类型为复诊
                if ($val['outpatient_type_id'] == OutpatientType::ID_CONTINUE_VISIT) {
                    // 复诊总消费
                    if (isset($arr[$val[$paramsId]]['return_visit_consumption'])) {
                        $arr[$val[$paramsId]]['return_visit_consumption'] += $val['reality_money'];
                    } else {
                        $arr[$val[$paramsId]]['return_visit_consumption'] = $val['reality_money'];
                    }
                }
            }
            foreach ($list3 as $val) {
                // 患者就诊类型为复诊
                if ($val['outpatient_type_id'] == OutpatientType::ID_CONTINUE_VISIT) {
                    // 复诊人数（状态为复诊的患者数）
                    if (isset($arr[$val[$paramsId]]['return_visit_num'])) {
                        $arr[$val[$paramsId]]['return_visit_num'] += 1;
                    } else {
                        $arr[$val[$paramsId]]['return_visit_num'] = 1;
                    }
                }
            }
            // 复诊人均
            foreach ($arr as $key => $val) {
                $arr[$key]['data'] = 0;
                if (isset($val['return_visit_num']) && $val['return_visit_num']) {
                    $arr[$key]['data'] = (isset($val['return_visit_consumption']) ? $val['return_visit_consumption'] : 0) / $val['return_visit_num'];
                }
            }
        } elseif ($params['check_type'] == 7) { //总人均
            foreach ($list1 as $val) {
                // 总消费
                if (isset($arr[$val[$paramsId]]['consumption'])) {
                    $arr[$val[$paramsId]]['consumption'] += $val['reality_money'];
                } else {
                    $arr[$val[$paramsId]]['consumption'] = $val['reality_money'];
                }
            }
            foreach ($list3 as $val) {
                // 患者就诊类型为复诊
                if ($val['outpatient_type_id'] == OutpatientType::ID_CONTINUE_VISIT) {
                    // 复诊人数（状态为复诊的患者数）
                    if (isset($arr[$val[$paramsId]]['return_visit_num'])) {
                        $arr[$val[$paramsId]]['return_visit_num'] += 1;
                    } else {
                        $arr[$val[$paramsId]]['return_visit_num'] = 1;
                    }
                }
            }
            foreach ($list3 as $val) {
                // 患者就诊类型为初诊
                if ($val['outpatient_type_id'] == OutpatientType::ID_FIRST_VISIT) {
                    // 初诊人数（状态为初诊的患者数）
                    if (isset($arr[$val[$paramsId]]['first_visit_num'])) {
                        $arr[$val[$paramsId]]['first_visit_num'] += 1;
                    } else {
                        $arr[$val[$paramsId]]['first_visit_num'] = 1;
                    }
                }
            }

            // 总人均
            foreach ($arr as $key => $val) {
                $arr[$key]['data'] = 0;
                if (!isset($val['return_visit_num']) || !$val['return_visit_num']) {
                    $val['return_visit_num'] = 0;
                }
                if (!isset($val['first_visit_num']) || !$val['first_visit_num']) {
                    $val['first_visit_num'] = 0;
                }
                $allNum = $val['return_visit_num'] + $val['first_visit_num'];
                if ($allNum) {
                    $arr[$key]['data'] = (isset($val['consumption']) ? $val['consumption'] : 0) / ($val['return_visit_num'] + $val['first_visit_num']);
                }
            }
        } elseif ($params['check_type'] == 8) { // 308人均使用
            foreach ($list2 as $val) {
                if ($val['type'] == UserTreatment::TYPE_TREAT) {
                    // 308使用总个数
                    if (isset($arr[$val[$paramsId]]['sum_use_308'])) {
                        $arr[$val[$paramsId]]['sum_use_308'] += $val['recently_clinic_num'] + $val['recently_surplus_num'];
                    } else {
                        $arr[$val[$paramsId]]['sum_use_308'] = $val['recently_clinic_num'] + $val['recently_surplus_num'];
                    }
                    // 308使用人数
                    $arr[$val[$paramsId]]['use_num_308'][] = $val['patient_card_id'];
                }
            }
            // 308人均使用
            foreach ($arr as $key => $val) {
                $arr[$key]['data'] = 0;
                if (isset($val['use_num_308']) && $val['use_num_308']) {
                    $useNum308 = count(array_unique($val['use_num_308']));
                    $arr[$key]['data'] = (isset($val['sum_use_308']) ? $val['sum_use_308'] : 0) / $useNum308;
                }
            }
        } elseif ($params['check_type'] == 9) { //308总人均
            foreach ($list2 as $val) {
                if ($val['type'] == UserTreatment::TYPE_ADD) {
                    // 308购买总个数
                    if (isset($arr[$val[$paramsId]]['sum_buy_308'])) {
                        $arr[$val[$paramsId]]['sum_buy_308'] += $val['recently_clinic_num'] + $val['recently_surplus_num'];
                    } else {
                        $arr[$val[$paramsId]]['sum_buy_308'] = $val['recently_clinic_num'] + $val['recently_surplus_num'];
                    }
                    // 308购买人数
                    $arr[$val[$paramsId]]['buy_num_308'][] = $val['patient_card_id'];
                }
                if ($val['type'] == UserTreatment::TYPE_REDUCE) {
                    // 308退费个数
                    if (isset($arr[$val[$paramsId]]['sum_buy_308'])) {
                        $arr[$val[$paramsId]]['sum_buy_308'] -= ($val['recently_clinic_num'] + $val['recently_surplus_num']);
                    } else {
                        $arr[$val[$paramsId]]['sum_buy_308'] = -($val['recently_clinic_num'] + $val['recently_surplus_num']);
                    }
                }
            }
            // 308人均使用
            foreach ($arr as $key => $val) {
                $arr[$key]['data'] = 0;
                if (isset($val['buy_num_308']) && $val['buy_num_308']) {
                    $buyNum308 = count(array_unique($val['buy_num_308']));
                    $arr[$key]['data'] = (isset($val['sum_buy_308']) ? $val['sum_buy_308'] : 0) / $buyNum308;
                }
            }
        }
        return $arr;
    }

    /**
     * 新增项目报表（月）
     *
     * @param $month
     * @return bool|int
     */
    public static function createProjectReport($month)
    {
        $startTime = strtotime($month);
        $endTime = strtotime($month . '+1 month') - 1;

        // 消费列表
        $consumption = Consumption::find()
            ->select([
                'a.project_id', 'a.patient_card_id', 'a.clinic_time',
                'a.reality_money', 'b.patient_diseases_id', 'b.outpatient_type_id'
            ])
            ->alias('a')
            ->innerJoin(User::tableName() . ' b', 'a.patient_card_id = b.patient_card_id and a.project_id = b.project_id')
            ->where(['between', 'a.clinic_time', $startTime, $endTime])
            ->andWhere(['b.status' => User::STATUS_ENABLE])
            ->asArray()
            ->all();


        // 一级病种
        $diseasesList = PatientDiseases::find()
            ->select('id')
            ->where(['status' => PatientDiseases::STATUS_ENABLE, 'pid' => 0])
            ->column();

        $arr = [0 => []];// 病种为0时也要统计
        foreach ($diseasesList as $val) {
            $arr[$val] = [];
        }

        // 挂号人数 => reg_time
        $patientNum1 = User::find()
            ->select(['project_id', 'patient_diseases_id', 'outpatient_type_id', 'patient_card_id'])
            ->where(['between', 'reg_time', $startTime, $endTime])
            ->andWhere(['status' => User::STATUS_ENABLE])
            ->asArray()
            ->all();

        // 挂号患者诊疗号数组
        $patientCardArr = [];

        foreach ($patientNum1 as $val) {
            // 按 病种 / 项目 筛选
            if (isset($arr[$val['patient_diseases_id']])) {
                // 挂号人数
                if (isset($arr[$val['patient_diseases_id']][$val['project_id']]['register_num'])) {
                    $arr[$val['patient_diseases_id']][$val['project_id']]['register_num'] += 1;
                } else {
                    $arr[$val['patient_diseases_id']][$val['project_id']]['register_num'] = 1;
                }
            }
            // 挂号患者诊疗号数组
            $patientCardArr[$val['patient_diseases_id']][$val['project_id']]['patient_card_id'][] = $val['patient_card_id'];
        }
        foreach ($consumption as $val) {
            // 按 病种 / 项目 筛选
            if (isset($arr[$val['patient_diseases_id']])) {
                // 总消费
                if (isset($arr[$val['patient_diseases_id']][$val['project_id']]['consumption'])) {
                    $arr[$val['patient_diseases_id']][$val['project_id']]['consumption'] += $val['reality_money'];
                } else {
                    $arr[$val['patient_diseases_id']][$val['project_id']]['consumption'] = $val['reality_money'];
                }

                // 挂号患者总消费
                if (
                    isset($patientCardArr[$val['patient_diseases_id']][$val['project_id']]['patient_card_id']) &&
                    in_array($val['patient_card_id'], $patientCardArr[$val['patient_diseases_id']][$val['project_id']]['patient_card_id'])
                ) {
                    if (isset($arr[$val['patient_diseases_id']][$val['project_id']]['register_consumption'])) {
                        $arr[$val['patient_diseases_id']][$val['project_id']]['register_consumption'] += $val['reality_money'];
                    } else {
                        $arr[$val['patient_diseases_id']][$val['project_id']]['register_consumption'] = $val['reality_money'];
                    }
                }

                // 患者就诊类型为初诊
                if ($val['outpatient_type_id'] == OutpatientType::ID_FIRST_VISIT) {
                    // 初诊总消费
                    if (isset($arr[$val['patient_diseases_id']][$val['project_id']]['first_visit_consumption'])) {
                        $arr[$val['patient_diseases_id']][$val['project_id']]['first_visit_consumption'] += $val['reality_money'];
                    } else {
                        $arr[$val['patient_diseases_id']][$val['project_id']]['first_visit_consumption'] = $val['reality_money'];
                    }
                }
                // 患者就诊类型为复诊
                if ($val['outpatient_type_id'] == OutpatientType::ID_CONTINUE_VISIT) {
                    // 复诊总消费
                    if (isset($arr[$val['patient_diseases_id']][$val['project_id']]['return_visit_consumption'])) {
                        $arr[$val['patient_diseases_id']][$val['project_id']]['return_visit_consumption'] += $val['reality_money'];
                    } else {
                        $arr[$val['patient_diseases_id']][$val['project_id']]['return_visit_consumption'] = $val['reality_money'];
                    }
                }
            }
        }

        // 初复诊人数 => last_revisiting_time
        $patientNum2 = User::find()
            ->select(['project_id', 'patient_diseases_id', 'outpatient_type_id'])
            ->where(['between', 'last_revisiting_time', $startTime, $endTime])
            ->andWhere(['status' => User::STATUS_ENABLE])
            ->asArray()
            ->all();

        foreach ($patientNum2 as $val) {
            // 按 病种 / 项目 筛选
            if (isset($arr[$val['patient_diseases_id']])) {
                // 患者就诊类型为初诊
                if ($val['outpatient_type_id'] == OutpatientType::ID_FIRST_VISIT) {
                    // 初诊人数（状态为初诊的患者数）
                    if (isset($arr[$val['patient_diseases_id']][$val['project_id']]['first_visit_num'])) {
                        $arr[$val['patient_diseases_id']][$val['project_id']]['first_visit_num'] += 1;
                    } else {
                        $arr[$val['patient_diseases_id']][$val['project_id']]['first_visit_num'] = 1;
                    }
                }
                // 患者就诊类型为复诊
                if ($val['outpatient_type_id'] == OutpatientType::ID_CONTINUE_VISIT) {
                    // 复诊人数（状态为复诊的患者数）
                    if (isset($arr[$val['patient_diseases_id']][$val['project_id']]['return_visit_num'])) {
                        $arr[$val['patient_diseases_id']][$val['project_id']]['return_visit_num'] += 1;
                    } else {
                        $arr[$val['patient_diseases_id']][$val['project_id']]['return_visit_num'] = 1;
                    }
                }
            }
        }

        $treatList = UserTreatment::find()
            ->select([
                'a.project_id', 'a.patient_card_id', 'a.recently_clinic_time', 'a.type',
                'a.recently_clinic_num', 'a.recently_surplus_num', 'b.patient_diseases_id', 'b.outpatient_type_id',
            ])
            ->alias('a')
            ->innerJoin(User::tableName() . ' b', 'a.patient_card_id = b. patient_card_id and a.project_id = b.project_id')
            ->innerJoin(Project::tableName() . ' c', ' a.clinic_project_id = c.id and a.project_id = c.project_id')
            ->where(['between', 'a.recently_clinic_time', $startTime, $endTime])
            ->andWhere([
                'c.template' => Project::TEMPLATE_308,
                'b.status' => User::STATUS_ENABLE
            ])
            ->asArray()
            ->all();

        foreach ($treatList as $val) {
            if ($val['type'] == UserTreatment::TYPE_TREAT) {
                // 308使用总个数
                if (isset($arr[$val['patient_diseases_id']][$val['project_id']]['sum_use_308'])) {
                    $arr[$val['patient_diseases_id']][$val['project_id']]['sum_use_308'] += $val['recently_clinic_num'] + $val['recently_surplus_num'];
                } else {
                    $arr[$val['patient_diseases_id']][$val['project_id']]['sum_use_308'] = $val['recently_clinic_num'] + $val['recently_surplus_num'];
                }
                // 308使用人数
                $arr[$val['patient_diseases_id']][$val['project_id']]['use_num_308'][] = $val['patient_card_id'];
            }

            if (in_array($val['type'], [UserTreatment::TYPE_ADD, UserTreatment::TYPE_REDUCE])) {
                if ($val['type'] == UserTreatment::TYPE_ADD) {
                    // 308购买总个数
                    if (isset($arr[$val['patient_diseases_id']][$val['project_id']]['sum_buy_308'])) {
                        $arr[$val['patient_diseases_id']][$val['project_id']]['sum_buy_308'] += ($val['recently_clinic_num'] + $val['recently_surplus_num']);
                    } else {
                        $arr[$val['patient_diseases_id']][$val['project_id']]['sum_buy_308'] = ($val['recently_clinic_num'] + $val['recently_surplus_num']);
                    }

                    // 308购买人数
                    $arr[$val['patient_diseases_id']][$val['project_id']]['buy_num_308'][] = $val['patient_card_id'];
                }
                if ($val['type'] == UserTreatment::TYPE_REDUCE) {
                    // 308购买总个数
                    if (isset($arr[$val['patient_diseases_id']][$val['project_id']]['sum_buy_308'])) {
                        $arr[$val['patient_diseases_id']][$val['project_id']]['sum_buy_308'] -= ($val['recently_clinic_num'] + $val['recently_surplus_num']);
                    } else {
                        $arr[$val['patient_diseases_id']][$val['project_id']]['sum_buy_308'] = -($val['recently_clinic_num'] + $val['recently_surplus_num']);
                    }
                }

            }
        }
        $addArr = [];
        foreach ($arr as $key => $val) {
            foreach ($val as $k => $p) {
                $addArr[] = [
                        'project_id'=> $k,
                        'month' => $startTime,
                        'diseases_id' => $key,
                        'consumption' => $p['consumption'] ?? 0,
                        'register_consumption' => $p['register_consumption'] ?? 0,
                        'register_num' => $p['register_num'] ?? 0,
                        'first_visit_num' => $p['first_visit_num'] ?? 0,
                        'first_visit_consumption' => $p['first_visit_consumption'] ?? 0,
                        'return_visit_num' => $p['return_visit_num'] ?? 0,
                        'return_visit_consumption' => $p['return_visit_consumption'] ?? 0,
                        'sum_use_308' => $p['sum_use_308'] ?? 0,
                        'use_num_308' => isset($p['use_num_308']) && $p['use_num_308'] ? count(array_unique($p['use_num_308'])) : 0,// 308使用人数去重
                        'sum_buy_308' => $p['sum_buy_308'] ?? 0,
                        'buy_num_308' => isset($p['buy_num_308']) && $p['buy_num_308'] ? count(array_unique($p['buy_num_308'])) : 0,// 308购买人数去重
                        'created_at' => time(),
                        'updated_at' => time(),
                    ];
            }
        }
        $columns = [
            'project_id',
            'month',
            'diseases_id',
            'consumption',
            'register_consumption',
            'register_num',
            'first_visit_num',
            'first_visit_consumption',
            'return_visit_num',
            'return_visit_consumption',
            'sum_use_308',
            'use_num_308',
            'sum_buy_308',
            'buy_num_308',
            'created_at',
            'updated_at',
        ];
        if ($addArr) {
            return Yii::$app->db->createCommand()->batchInsert(
                ProjectReport::tableName(),
                $columns,
                $addArr
            )->execute();
        }
        return true;
    }

    /**
     * 医生报表列表
     *
     * @param array $params
     * @return array
     */
    public function getDoctorReportList(array $params = [])
    {
        $startTime = strtotime(date($params['start_time']));
        $endTime = strtotime(date($params['end_time'])) + 86399;
        $where = [];
        if (isset($params['patient_diseases_id'])) {
            if (is_numeric($params['patient_diseases_id'])) {// 数字包括0
                $where['b.patient_diseases_id'] = $params['patient_diseases_id'];
            } elseif ($params['patient_diseases_id']) { //字符串1,2
                $diseasesIds = explode(',', $params['patient_diseases_id']);
                if ($diseasesIds) {
                    $where['b.patient_diseases_id'] = $diseasesIds;
                }
            } else {
                $diseasesList = PatientDiseases::find()
                    ->select('id')
                    ->where(['status' => PatientDiseases::STATUS_ENABLE, 'pid' => 0])
                    ->column();
                array_push($diseasesList, 0);
                $where['b.patient_diseases_id'] = $diseasesList;
            }
        }
        $list1 = [];
        $list2 = [];
        $list3 = [];
        if (in_array($params['check_type'], [1,2,4,6,7])) { // 消费列表
            $list1 = Consumption::find()
                ->select([
                    'a.project_id', 'a.patient_card_id', 'a.clinic_time',
                    'a.reality_money', 'b.patient_diseases_id', 'b.outpatient_type_id', 'c.id doctor_id'
                ])
                ->alias('a')
                ->innerJoin(User::tableName() . ' b', 'a.patient_card_id = b. patient_card_id and a.project_id = b.project_id')
                ->leftJoin(Doctor::tableName() . ' c', 'b.clinic_id = c.clinic_id')
                ->where([
                    'and',
                    ['between', 'a.clinic_time', $startTime, $endTime],
                    ['c.status' => Doctor::STATUS_ENABLE, 'b.status' => User::STATUS_ENABLE]
                ])
                ->andWhere($where)
                ->asArray()
                ->all();
        }
        if (in_array($params['check_type'], [8,9])) { // 308人均使用、308人均购买
            $list2 = UserTreatment::find()
                ->select([
                    'a.project_id', 'a.patient_card_id', 'a.recently_clinic_time', 'a.type', 'a.clinic_id',
                    'a.recently_clinic_num', 'a.recently_surplus_num', 'b.patient_diseases_id', 'b.outpatient_type_id', 'd.id doctor_id'
                ])
                ->alias('a')
                ->innerJoin(User::tableName() . ' b', 'a.patient_card_id = b. patient_card_id and a.project_id = b.project_id')
                ->innerJoin(Project::tableName() . ' c', ' a.clinic_project_id = c.id and a.project_id = c.project_id')
                ->leftJoin(Doctor::tableName() . ' d', 'a.clinic_id = d.clinic_id')
                ->where([
                    'and',
                    [
                        'c.template' => Project::TEMPLATE_308,
                        'd.status' => Doctor::STATUS_ENABLE,
                        'b.status' => User::STATUS_ENABLE
                    ],
                    ['>=', 'a.recently_clinic_time', $startTime],
                    ['<=', 'a.recently_clinic_time', $endTime]
                ])
                ->andWhere($where)
                ->asArray()
                ->all();
        }
        if (in_array($params['check_type'], [2,3,4,5,6,7])) { // 人数
            if (in_array($params['check_type'], [3,4,5,6,7])) {
                $timeIs = 'b.last_revisiting_time';
            } else {
                $timeIs = 'b.reg_time';
            }
            $list3 = User::find()
                ->alias('b')
                ->select(['b.patient_diseases_id', 'b.outpatient_type_id', 'b.project_id', 'b.patient_card_id', 'c.id doctor_id'])
                ->leftJoin(Doctor::tableName() . ' c', 'b.clinic_id = c.clinic_id')
                ->where([
                    'and',
                    ['b.status' => User::STATUS_ENABLE, 'c.status' => Doctor::STATUS_ENABLE],
                    ['>=', $timeIs, $startTime],
                    ['<=', $timeIs, $endTime]
                ])
                ->andWhere($where)
                ->asArray()
                ->all();
        }
        // 列表返回
        $arr = $this->getListPageFormat($list1, $list2, $list3, $params, 'doctor_id');
        // return $arr;
        $finalArr = [];
        // 绑定项目列表
        $projectList = CommonService::getBindProjectList();
        if ($arr) {
            foreach ($arr as $key => $val) {
                $doctorIs = Doctor::findOne($key);
                $doctorName = $doctorIs ? $doctorIs->name : '';
                $projectId = 0;
                $projectName = '';
                $status = 0;// 能否点详细
                if (in_array($key, array_column($projectList, 'id'))) {
                    $status = 1;
                }
                if ($doctorIs && $doctorIs->project_id) {
                    $projectIs = \common\models\base\Project::findOne($doctorIs->project_id);
                    $projectName = $projectIs ? $projectIs->name : '';
                    $projectId = $projectIs ? $projectIs->id : '';
                }
                $finalArr[] = [
                    'data' => round($val['data'], 2),
                    'doctor_id' => $key,
                    'name' => $doctorName,
                    'rank' => '-',
                    'status' => $status,
                    'project_id' => $projectId,
                    'project_name' => $projectName,
                ];
            }
            array_multisort($finalArr, SORT_DESC);
        }
        return $this->compareLastMonth($params, $finalArr, 1);
    }

    /**
     * 新增医生报表（月）
     *
     * @param $month
     * @return bool|int
     */
    public static function createDoctorReport($month)
    {
        $startTime = strtotime(date($month));
        $endTime = strtotime(date($month) . '+1 month') - 1;

        // 消费列表
        $consumption = Consumption::find()
            ->select([
                'a.project_id', 'a.patient_card_id', 'a.clinic_time',
                'a.reality_money', 'b.patient_diseases_id', 'b.outpatient_type_id', 'c.id doctor_id'
            ])
            ->alias('a')
            ->innerJoin(User::tableName() . ' b', 'a.patient_card_id = b. patient_card_id and a.project_id = b.project_id')
            ->leftJoin(Doctor::tableName() . ' c', 'b.clinic_id = c.clinic_id')
            ->where([
                'and',
                ['c.status' => Doctor::STATUS_ENABLE, 'b.status' => User::STATUS_ENABLE],
                ['between', 'a.clinic_time', $startTime, $endTime],
                // ['>', 'a.reality_money', 0]
            ])
            ->asArray()
            ->all();


        // 一级病种
        $diseasesList = PatientDiseases::find()
            ->select('id')
            ->where(['status' => PatientDiseases::STATUS_ENABLE, 'pid' => 0])
            ->column();
        $arr = [];
        foreach ($diseasesList as $val) {
            $arr[$val] = [];
        }

        // 挂号人数 => reg_time
        $patientNum1 = User::find()
            ->alias('b')
            ->select(['b.clinic_id', 'b.patient_diseases_id', 'b.outpatient_type_id', 'b.patient_card_id', 'c.id doctor_id'])
            ->leftJoin(Doctor::tableName() . ' c', 'b.clinic_id = c.clinic_id')
            ->where([
                'and',
                ['between', 'b.reg_time', $startTime, $endTime],
                ['c.status' => Doctor::STATUS_ENABLE, 'b.status' => User::STATUS_ENABLE]
            ])
            ->asArray()
            ->all();

        // 挂号患者诊疗号数组
        $patientCardArr = [];

        foreach ($patientNum1 as $val) {
            // 按 病种 / 项目 筛选
            if (isset($arr[$val['patient_diseases_id']])) {
                // 挂号人数
                if (isset($arr[$val['patient_diseases_id']][$val['doctor_id']]['register_num'])) {
                    $arr[$val['patient_diseases_id']][$val['doctor_id']]['register_num'] += 1;
                } else {
                    $arr[$val['patient_diseases_id']][$val['doctor_id']]['register_num'] = 1;
                }
                // 挂号患者诊疗号数组
                $patientCardArr[$val['patient_diseases_id']][$val['doctor_id']]['patient_card_id'][] = $val['patient_card_id'];
            }
        }

        foreach ($consumption as $val) {
            // 按 病种 / 项目 筛选
            if (isset($arr[$val['patient_diseases_id']])) {
                // 总消费
                if (isset($arr[$val['patient_diseases_id']][$val['doctor_id']]['consumption'])) {
                    $arr[$val['patient_diseases_id']][$val['doctor_id']]['consumption'] += $val['reality_money'];
                } else {
                    $arr[$val['patient_diseases_id']][$val['doctor_id']]['consumption'] = $val['reality_money'];
                }

                // 挂号患者总消费
                if (
                    isset($patientCardArr[$val['patient_diseases_id']][$val['doctor_id']]['patient_card_id']) &&
                    in_array($val['patient_card_id'], $patientCardArr[$val['patient_diseases_id']][$val['doctor_id']]['patient_card_id'])
                ) {
                    if (isset($arr[$val['patient_diseases_id']][$val['doctor_id']]['register_consumption'])) {
                        $arr[$val['patient_diseases_id']][$val['doctor_id']]['register_consumption'] += $val['reality_money'];
                    } else {
                        $arr[$val['patient_diseases_id']][$val['doctor_id']]['register_consumption'] = $val['reality_money'];
                    }
                }

                // 患者就诊类型为初诊
                if ($val['outpatient_type_id'] == OutpatientType::ID_FIRST_VISIT) {
                    // 初诊总消费
                    if (isset($arr[$val['patient_diseases_id']][$val['doctor_id']]['first_visit_consumption'])) {
                        $arr[$val['patient_diseases_id']][$val['doctor_id']]['first_visit_consumption'] += $val['reality_money'];
                    } else {
                        $arr[$val['patient_diseases_id']][$val['doctor_id']]['first_visit_consumption'] = $val['reality_money'];
                    }
                }
                // 患者就诊类型为复诊
                if ($val['outpatient_type_id'] == OutpatientType::ID_CONTINUE_VISIT) {
                    // 复诊总消费
                    if (isset($arr[$val['patient_diseases_id']][$val['doctor_id']]['return_visit_consumption'])) {
                        $arr[$val['patient_diseases_id']][$val['doctor_id']]['return_visit_consumption'] += $val['reality_money'];
                    } else {
                        $arr[$val['patient_diseases_id']][$val['doctor_id']]['return_visit_consumption'] = $val['reality_money'];
                    }
                }
            }
        }

        // 初复诊人数 => last_revisiting_time
        $patientNum2 = User::find()
            ->alias('b')
            ->select(['b.clinic_id', 'b.patient_diseases_id', 'b.outpatient_type_id', 'c.id doctor_id'])
            ->leftJoin(Doctor::tableName() . ' c', 'b.clinic_id = c.clinic_id')
            ->where([
                'and',
                ['between', 'b.last_revisiting_time', $startTime, $endTime],
                ['c.status' => Doctor::STATUS_ENABLE, 'b.status' => User::STATUS_ENABLE]
            ])
            ->asArray()
            ->all();

        foreach ($patientNum2 as $val) {
            // 按 病种 / 项目 筛选
            if (isset($arr[$val['patient_diseases_id']])) {
                // 患者就诊类型为初诊
                if ($val['outpatient_type_id'] == OutpatientType::ID_FIRST_VISIT) {
                    // 初诊人数（状态为初诊的患者数）
                    if (isset($arr[$val['patient_diseases_id']][$val['doctor_id']]['first_visit_num'])) {
                        $arr[$val['patient_diseases_id']][$val['doctor_id']]['first_visit_num'] += 1;
                    } else {
                        $arr[$val['patient_diseases_id']][$val['doctor_id']]['first_visit_num'] = 1;
                    }
                }
                // 患者就诊类型为复诊
                if ($val['outpatient_type_id'] == OutpatientType::ID_CONTINUE_VISIT) {
                    // 复诊人数（状态为复诊的患者数）
                    if (isset($arr[$val['patient_diseases_id']][$val['doctor_id']]['return_visit_num'])) {
                        $arr[$val['patient_diseases_id']][$val['doctor_id']]['return_visit_num'] += 1;
                    } else {
                        $arr[$val['patient_diseases_id']][$val['doctor_id']]['return_visit_num'] = 1;
                    }
                }
            }
        }

        $treatList = UserTreatment::find()
            ->select([
                'a.project_id', 'a.patient_card_id', 'a.recently_clinic_time', 'a.type', 'a.clinic_id',
                'a.recently_clinic_num', 'a.recently_surplus_num', 'b.patient_diseases_id', 'b.outpatient_type_id', 'd.id doctor_id'
            ])
            ->alias('a')
            ->innerJoin(User::tableName() . ' b', 'a.patient_card_id = b. patient_card_id and  a.project_id = b.project_id')
            ->innerJoin(Project::tableName() . ' c', ' a.clinic_project_id = c.id and  a.project_id = c.project_id')
            ->leftJoin(Doctor::tableName() . ' d', 'a.clinic_id = d.clinic_id')
            ->where(['between', 'a.recently_clinic_time', $startTime, $endTime])
            ->andWhere([
                'c.template' => Project::TEMPLATE_308,
                'c.status' => Doctor::STATUS_ENABLE,
                'b.status' => User::STATUS_ENABLE
            ])
            ->asArray()
            ->all();

        foreach ($treatList as $val) {
            if ($val['type'] == UserTreatment::TYPE_TREAT) {
                // 308使用总个数
                if (isset($arr[$val['patient_diseases_id']][$val['doctor_id']]['sum_use_308'])) {
                    $arr[$val['patient_diseases_id']][$val['doctor_id']]['sum_use_308'] += $val['recently_clinic_num'] + $val['recently_surplus_num'];
                } else {
                    $arr[$val['patient_diseases_id']][$val['doctor_id']]['sum_use_308'] = $val['recently_clinic_num'] + $val['recently_surplus_num'];
                }
                // 308使用人数
                $arr[$val['patient_diseases_id']][$val['doctor_id']]['use_num_308'][] = $val['patient_card_id'];
            }

            if ($val['type'] == UserTreatment::TYPE_ADD) {
                // 308购买总个数
                if (isset($arr[$val['patient_diseases_id']][$val['doctor_id']]['sum_buy_308'])) {
                    $arr[$val['patient_diseases_id']][$val['doctor_id']]['sum_buy_308'] += $val['recently_clinic_num'] + $val['recently_surplus_num'];
                } else {
                    $arr[$val['patient_diseases_id']][$val['doctor_id']]['sum_buy_308'] = $val['recently_clinic_num'] + $val['recently_surplus_num'];
                }
                // 购买人数
                $arr[$val['patient_diseases_id']][$val['doctor_id']]['buy_num_308'][] = $val['patient_card_id'];
            }
            if ($val['type'] == UserTreatment::TYPE_REDUCE) {
                // 308购买总个数
                if (isset($arr[$val['patient_diseases_id']][$val['doctor_id']]['sum_buy_308'])) {
                    $arr[$val['patient_diseases_id']][$val['doctor_id']]['sum_buy_308'] -= ($val['recently_clinic_num'] + $val['recently_surplus_num']);
                } else {
                    $arr[$val['patient_diseases_id']][$val['doctor_id']]['sum_buy_308'] = -($val['recently_clinic_num'] + $val['recently_surplus_num']);
                }
            }
        }

        $addArr = [];
        foreach ($arr as $key => $val) {
            foreach ($val as $k => $p) {
                $projectIs = Doctor::findOne($k);
                // 医生存在项目则保存
                if ($projectIs && $projectIs->project_id) {
                    $addArr[] = [
                        'project_id' => $projectIs->project_id,
                        'doctor_id'=> $k,
                        'month' => $startTime,
                        'diseases_id' => $key,
                        'consumption' => $p['consumption'] ?? 0,
                        'register_consumption' => $p['register_consumption'] ?? 0,
                        'register_num' => $p['register_num'] ?? 0,
                        'first_visit_num' => $p['first_visit_num'] ?? 0,
                        'first_visit_consumption' => $p['first_visit_consumption'] ?? 0,
                        'return_visit_num' => $p['return_visit_num'] ?? 0,
                        'return_visit_consumption' => $p['return_visit_consumption'] ?? 0,
                        'sum_use_308' => $p['sum_use_308'] ?? 0,
                        'use_num_308' => isset($p['use_num_308']) && $p['use_num_308'] ? count(array_unique($p['use_num_308'])) : 0,// 308使用人数去重
                        'sum_buy_308' => $p['sum_buy_308'] ?? 0,
                        'buy_num_308' => isset($p['buy_num_308']) && $p['buy_num_308'] ? count(array_unique($p['buy_num_308'])) : 0,// 308购买人数去重
                        'created_at' => time(),
                        'updated_at' => time(),
                    ];
                }
            }
        }
        $columns = [
            'project_id',
            'doctor_id',
            'month',
            'diseases_id',
            'consumption',
            'register_consumption',
            'register_num',
            'first_visit_num',
            'first_visit_consumption',
            'return_visit_num',
            'return_visit_consumption',
            'sum_use_308',
            'use_num_308',
            'sum_buy_308',
            'buy_num_308',
            'created_at',
            'updated_at',
        ];
        if ($addArr) {
            return Yii::$app->db->createCommand()->batchInsert(
                ProjectReport::tableName(),
                $columns,
                $addArr
            )->execute();
        }
        return true;
    }

    /**
     * 计算排名
     *
     * @param array $params
     * @param array $list
     * @param int $rankType 0：项目 1：医生
     * @return array
     */
    public function compareLastMonth(array $params = [], array $list = [], int $rankType = 0)
    {
        $startMonth = date('m', strtotime(date($params['start_time'])));
        $startYear = date ( 'Y', strtotime(date($params['start_time'])));
        $endMonth = date('m', strtotime(date($params['end_time'])));
        if ($startMonth == 1) {
            $lastMonth = 12;
            $lastYear = $startYear - 1;
        } else {
            $lastMonth = $startMonth - 1;
            $lastYear = $startYear;
        }
        $lastStartMonth = $lastYear . '-' . $lastMonth . '-1' ;
        $startTime = strtotime($lastStartMonth); //上个月的月初时间戳

        // 不是一个月则不计算排名差值
        if ($startMonth != $endMonth) {
            return $list;
        }
        $selectList = ['id', 'project_id', 'doctor_id', 'month', 'diseases_id'];
        if ($params['check_type'] == 1) {
            $selectList[] = 'sum(consumption) data';
        } elseif ($params['check_type'] == 2) {
            $selectList[] = 'sum(register_consumption) register_consumption';
            $selectList[] = 'sum(register_num) register_num';
            $selectList[] = 'case when register_num != 0 then (register_consumption/register_num) else 0 end data';
        } elseif ($params['check_type'] == 3) {
            $selectList[] = 'sum(first_visit_num) data';
        } elseif ($params['check_type'] == 4) {
            $selectList[] = 'sum(first_visit_consumption) first_visit_consumption';
            $selectList[] = 'sum(first_visit_num) first_visit_num';
            $selectList[] = 'case when first_visit_num != 0 then (first_visit_consumption/first_visit_num) else 0 end data';
        } elseif ($params['check_type'] == 5) {
            $selectList[] = 'sum(return_visit_num) data';
        } elseif ($params['check_type'] == 6) {
            $selectList[] = 'sum(return_visit_consumption) return_visit_consumption';
            $selectList[] = 'sum(return_visit_num) return_visit_num';
            $selectList[] = 'case when return_visit_num != 0 then (return_visit_consumption/return_visit_num) else 0 end data';
        } elseif ($params['check_type'] == 7) {
            $selectList[] = 'sum(consumption) consumption';
            $selectList[] = 'sum(first_visit_num) first_visit_num';
            $selectList[] = 'sum(return_visit_num) return_visit_num';
            $selectList[] = 'case when (first_visit_num + return_visit_num > 0) then (return_visit_consumption/(first_visit_num + return_visit_num)) else 0 end data';
        } elseif ($params['check_type'] == 8) {
            $selectList[] = 'sum(sum_use_308) sum_use_308';
            $selectList[] = 'sum(use_num_308) use_num_308';
            $selectList[] = 'case when use_num_308 != 0 then (sum_use_308/use_num_308) else 0 end data';
        } elseif ($params['check_type'] == 9) {
            $selectList[] = 'sum(sum_buy_308) sum_buy_308';
            $selectList[] = 'sum(buy_num_308) buy_num_308';
            $selectList[] = 'case when buy_num_308 != 0 then (sum_buy_308/buy_num_308) else 0 end data';
        }

        if (isset($params['patient_diseases_id'])) {
            if (is_numeric($params['patient_diseases_id'])) {// 数字包括0
                $where['diseases_id'] = $params['patient_diseases_id'];
            } elseif ($params['patient_diseases_id']) { //字符串1,2
                $diseasesIds = explode(',', $params['patient_diseases_id']);
                if ($diseasesIds) {
                    $where['diseases_id'] = $diseasesIds;
                }
            }
        }

        $where['month'] = $startTime;

        // 医生排名
        if ($rankType == 1) {
            $andWhere = ['!=', 'doctor_id', 0];
            $paramsType = 'doctor_id';
        } else {
            $andWhere = ['doctor_id' => 0];
            $paramsType = 'project_id';
        }
        // 上个月排名
        $report = ProjectReport::find()
            ->select($selectList)
            ->where($where)
            ->andWhere($andWhere)
            ->orderBy(['data' => SORT_DESC])
            ->groupBy($paramsType)
            ->asArray()
            ->all();
        $lastRank = [];
        foreach ($report as $rk => $rv) {
            $lastRank[$rv[$paramsType]] = $rk+1;
        }
        // 计算排名差值
        foreach ($list as $key => &$val) {
            if (isset($lastRank[$val[$paramsType]]) && $lastRank[$val[$paramsType]]) {
                $val['rank'] = $lastRank[$val[$paramsType]] - ($key + 1);
                if ($val['rank'] == 0) {
                    $val['rank'] = '-';
                }
            }
            // unset($val['data']);
        }

        return $list;
    }

    /**
     * 一级病种列表
     */
    public function getParentDiseasesList()
    {
        // 一级病种
        $diseasesOne = Yii::$app->services->patientDiseases->findList([
            'select' => ['id', 'diseases_name AS name', 'status'],
            'pid' => 0,
            // 'status' => [PatientDiseases::STATUS_ENABLE, PatientDiseases::STATUS_INVALID],
            'status' => PatientDiseases::STATUS_ENABLE,
        ]);
        $diseases0 = User::find()->select('id')->where(['patient_diseases_id' => 0])->limit(1)->one();
        if ($diseases0) {
            array_push($diseasesOne, ['id' => 0, 'name' => '未填病种']);
        }
        return $diseasesOne;
    }
}
